package com.jic.filecenter.service.upload;

import com.google.common.collect.Maps;
import com.jic.common.base.vo.RestResult;
import com.jic.filecenter.common.FileUtil;
import com.jic.filecenter.controller.errors.FileCenterErrorCode;
import com.jic.filecenter.controller.errors.FileCenterException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.multipart.MultipartFile;

import javax.activation.MimetypesFileTypeMap;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;

@Service
@Slf4j
public class FileUploadService {

    @Value("${file.upload.path}")
    private String fileUploadPath;

    @Value("${file.cdn.url}")
    private String imageCDN;

    /**
     * 文件上传到本地目录
     * @param file
     * @param type
     * @return
     * @throws Throwable
     */
    public RestResult<Map> fileUpload(MultipartFile file, String type) throws Throwable {
        if (file == null || file.isEmpty()) {
            log.info("Please select the file to upload");
            throw new FileCenterException(FileCenterErrorCode.FILE_NOT_SELECT);
        }
        // 创建目录
        String datePath = getFielDatePath();
        String filePath = new File(fileUploadPath + "/" + datePath).getAbsolutePath();
        File fileUpload = new File(filePath);
        if (!fileUpload.exists()) {
            if(!fileUpload.mkdirs()){
                log.info("Directories crate fail");
                throw new FileCenterException(FileCenterErrorCode.DIRECTORIES_CRATE_FAIL);
            }
        }
        String filename = getFilename(datePath,DigestUtils.md5Hex(file.getInputStream()), file.getOriginalFilename());
        // 判断文件是否存在
        fileUpload = new File(filePath,filename);
        if(fileUpload.exists()){
            log.info("File Exists,Delete Old");
            fileUpload.delete();
        }
        // 上传文件
        try {
            file.transferTo(fileUpload);
        } catch (IOException e) {
           log.error("File Upload Fial",e);
            throw new FileCenterException(FileCenterErrorCode.FILE_UPLAOD_ERROR);
        }
        String uri = new StringBuilder().append(imageCDN).append("/").append(datePath)
                                        .append("/").append(filename).toString();
        Map<String, String> resultMap = Maps.newHashMap();
        resultMap.put("imageUrl",uri);
        resultMap.put("imgUrl",uri);
        return RestResult.success(resultMap);
    }

    /**
     * 文件下载
     * @param filename
     * @throws Throwable
     */
    public void fileDownload(String filename) throws Throwable {
        String datePath = filename.substring(0,filename.indexOf("_"));
        String downloadPath = new StringBuilder().append(fileUploadPath).append("/").append(datePath).toString();
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletResponse response = requestAttributes.getResponse();
        // 设置信息给客户端不解析
        String type = new MimetypesFileTypeMap().getContentType(filename);
        // 设置contenttype，即告诉客户端所发送的数据属于什么类型
        response.setHeader("Content-type",type);
        // 设置编码
        String hehe = new String(filename.getBytes("utf-8"), "iso-8859-1");
        // 设置扩展头，当Content-Type 的类型为要下载的类型时 , 这个信息头会告诉浏览器这个文件的名字和类型。
        response.setHeader("Content-Disposition", "attachment;filename=" + hehe);
        FileUtil.download(filename, downloadPath, response);
    }


    /**
     * 获取文件日期目录
     * @return
     */
    private String getFielDatePath(){
        Date dt = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        return  sdf.format(dt);
    }

    /**
     * 获取上传存储的文件名称
     * @param fileMd5
     * @param filename
     * @return
     */
    private String getFilename(String datePath, String fileMd5, String filename) {
        String suffix = filename.substring(filename.lastIndexOf("."), filename.length());
        filename = new StringBuilder().append(datePath).append("_").append(fileMd5).append(suffix).toString();
        return filename;
    }

}
